package copyengine.resource.resProxy.cacheData
{
    import copyengine.log.CELog;
    import copyengine.resource.resProxy.CEResFIleDesc;
    import copyengine.resource.resProxy.cachePool.CEResCachePool;

    /**
     * 用户Hold每个加载进来的资源
     */
    public class CEResCacheDataBasic
    {
        protected var mIsLoaded:Boolean;
        protected var mFileDesc:CEResFIleDesc;

        private var mReferenceCount:int = 0;
        private var mAllOnCompleteCallbackVector:Vector.<Function>;
        private var mAllInProgressCallbackVector:Vector.<Function>;
        private var mAllOnErrorCallbackVector:Vector.<Function>;

        public function CEResCacheDataBasic()
        {
            mAllOnCompleteCallbackVector = new Vector.<Function>();
            mAllInProgressCallbackVector = new Vector.<Function>();
            mAllOnErrorCallbackVector = new Vector.<Function>();
        }

        public final function setFileDesc(_fileDesc:CEResFIleDesc):void
        {
            mFileDesc = _fileDesc;
        }

        public final function loadRes(_onComplete:Function, _inProgress:Function, _onError:Function):void
        {
            _onComplete != null && mAllOnCompleteCallbackVector.push(_onComplete);
            _inProgress != null && mAllInProgressCallbackVector.push(_inProgress);
            _onError != null && mAllOnErrorCallbackVector.push(_onError);
            if (mIsLoaded) {
                CELog.err("CEResCacheDataBasic->already load but call loadRes , file: " + mFileDesc.toString());
                onResLoadComplete();
            } else {
                doLoadRes();
            }
        }

        /**
         * 返回当前资源是否已经被加载过了
         */
        public final function isLoaded():Boolean
        {return mIsLoaded;}

        //====================//
        //==Protected  Function
        //===================//

        protected final function onResLoadComplete():void
        {
            CELog.log("file: " + mFileDesc.fileName + " load complete", "CERes");
            mIsLoaded = true;
            while (mAllOnCompleteCallbackVector.length > 0) {
                mAllOnCompleteCallbackVector.pop()();
            }
            mAllOnErrorCallbackVector.length = 0;
            mAllInProgressCallbackVector.length = 0;
        }

        protected final function onResLoadInProgress():void {}

        protected final function onResLoadInError():void {}

        /**
         * 资源的名称,可以后期指定,如果未指定则为文件名+后缀构成
         * 比如 http://xxx.yyy.com/res/GUI.swf 文件名则为GUI.swf
         *
         * 当加载图片时候,一般就直接用加载的地址作为ResName,(后期指定)
         * 比如 http://xxx.yyy.com/res/1.png 那最终的ResName就用这个链接,这样调用方便
         */
        public final function getResName():String
        {return mFileDesc.fileName;}

        /**
         * 增加资源引用计数
         */
        public final function addReferenceCount():void
        {mReferenceCount++;}

        /**
         * 减少资源引用计数
         *
         * 在CEResProxy中仅仅可以减少引用计数,该资源是否会被销毁由内部自行判断
         * CEResProxy不负责资源的销毁
         */
        public final function subReferenceCount():void
        {
            mReferenceCount--;
            if (mReferenceCount <= 0 && isCanDispose()) {
                dispose();
                CEResCachePool.instance.deleteResCacheData(mFileDesc.fileName);
                mIsLoaded = false;
            }
        }

        //=========================//
        //==OverrideAble  Function
        //==========================//

        /**
         * 标明当前的资源是否可以在引用计数为0的情况下卸载
         * 如果资源即时引用计数为0也不可以卸载则Override该方法返回false
         */
        protected function isCanDispose():Boolean
        {return true;}

        public function getData():*
        {
            CELog.err("CEResCacheDataBasic->Child should override this function");
            return null;
        }

        /**
         * RAW数据为加载进来的原始数据,比如Starling中的Texture,加载进来的原始数据可能为atf或者png
         * 该方法返回原始数据 用于上层函数进行缓存处理
         */
        public function getRAW():*
        {
            CELog.err("CEResCacheDataBasic->Child should override this function");
            return null;
        }

        protected function dispose():void
        {
        }

        protected function doLoadRes():void
        {
        }

    }

}
